import cv2
import numpy as np

#进行前景提取
"""def main():

    # 1.导入图片
    img_src = cv2.imread("d1f697398e534cffa8e2eb0e69476d07.jpeg")

    # 2.灰度处理与二值化
    img_gray = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY)
    ret, img_bin = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)

    # 3.连通域分析
    contours, hierarchy = cv2.findContours(img_bin, cv2.RETR_EXTERNAL,
                                                        cv2.CHAIN_APPROX_SIMPLE)

    # 4.制作掩膜图片
    img_mask = np.zeros(img_src.shape, np.uint8)
    cv2.drawContours(img_mask, contours, -1, (255, 255, 255), -1)

    # 5.执行与运算
    img_result = cv2.bitwise_and(img_src, img_mask)

    # 6.显示结果
    cv2.imshow("img_src", img_src)
    cv2.imshow("img_mask", img_mask)
    cv2.imshow("img_result", img_result)

    cv2.waitKey()
    cv2.destroyAllWindows()
"""

"""
#对比度增强-黑白
#全局直方图均衡化
def eaualHist_demo(image):
    gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)    #opencv的直方图均衡化要基于单通道灰度图像
#     cv2.namedWindow('input_image', cv.WINDOW_NORMAL)
#     cv2.imshow('input_image', gray)
    dst = cv2.equalizeHist(gray)                #自动调整图像对比度，把图像变得更清晰
    cv2.namedWindow("eaualHist_demo", cv2.WINDOW_NORMAL)
    cv2.imshow("eaualHist_demo", dst)
    return dst

#局部直方图均衡化
# def clahe_demo(image):
#     gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY)
#     clahe = cv.createCLAHE(5, (8,8))
#     dst = clahe.apply(gray)
#     cv.namedWindow("clahe_demo", cv.WINDOW_NORMAL)
#     cv.imshow("clahe_demo", dst)
# clahe_demo(src)
src=cv2.imread('d1f697398e534cffa8e2eb0e69476d07.jpeg')

dst = eaualHist_demo(src)
cv2.waitKey(0)
cv2.destroyAllWindows()"""
"""
if __name__ == '__main__':
    main()
"""


#彩色图像对比度增强
def getVarianceMean(scr, winSize):
    if scr is None or winSize is None:
        print("The input parameters of getVarianceMean Function error")
        return -1

    if winSize % 2 == 0:
        print("The window size should be singular")
        return -1

    copyBorder_map = cv2.copyMakeBorder(scr, winSize // 2, winSize // 2, winSize // 2, winSize // 2,
                                        cv2.BORDER_REPLICATE)
    shape = np.shape(scr)

    local_mean = np.zeros_like(scr)
    local_std = np.zeros_like(scr)

    for i in range(shape[0]):
        for j in range(shape[1]):
            temp = copyBorder_map[i:i + winSize, j:j + winSize]
            local_mean[i, j], local_std[i, j] = cv2.meanStdDev(temp)
            if local_std[i, j] <= 0:
                local_std[i, j] = 1e-8

    return local_mean, local_std



def adaptContrastEnhancement(scr, winSize, maxCg):
    if scr is None or winSize is None or maxCg is None:
        print("The input parameters of ACE Function error")
        return -1

    YUV_img = cv2.cvtColor(scr, cv2.COLOR_BGR2YUV)  ##转换通道
    Y_Channel = YUV_img[:, :, 0]
    shape = np.shape(Y_Channel)

    meansGlobal = cv2.mean(Y_Channel)[0]

    ##这里提供使用boxfilter 计算局部均质和方差的方法
    #    localMean_map=cv2.boxFilter(Y_Channel,-1,(winSize,winSize),normalize=True)
    #    localVar_map=cv2.boxFilter(np.multiply(Y_Channel,Y_Channel),-1,(winSize,winSize),normalize=True)-np.multiply(localMean_map,localMean_map)
    #    greater_Zero=localVar_map>0
    #    localVar_map=localVar_map*greater_Zero+1e-8
    #    localStd_map = np.sqrt(localVar_map)

    localMean_map, localStd_map = getVarianceMean(Y_Channel, winSize)

    for i in range(shape[0]):
        for j in range(shape[1]):

            cg = 0.2 * meansGlobal / localStd_map[i, j];
            if cg > maxCg:
                cg = maxCg
            elif cg < 1:
                cg = 1

            temp = Y_Channel[i, j].astype(float)
            temp = max(0, min(localMean_map[i, j] + cg * (temp - localMean_map[i, j]), 255))

            #            Y_Channel[i,j]=max(0,min(localMean_map[i,j]+cg*(Y_Channel[i,j]-localMean_map[i,j]),255))
            Y_Channel[i, j] = temp

    YUV_img[:, :, 0] = Y_Channel

    dst = cv2.cvtColor(YUV_img, cv2.COLOR_YUV2BGR)

    return dst

input_fn = 'input.jpg'

def main():
    img = cv2.imread(input_fn)

    if img is None:
        print("The file name error,please check it")
        return -1

    print(np.shape(img))
    dstimg = adaptContrastEnhancement(img, 15, 10)

    cv2.imwrite('output4.jpg', dstimg)
    cv2.waitKey(0)

    return 0



if __name__ == '__main__':
    main()

"""
#图像锐化

def custom_blur_demo(image):
    kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32)  # 锐化
    dst = cv2.filter2D(image, -1, kernel=kernel)
    return dst



src = cv2.imread("99a1699d6b8fda3f5c4ccdef3139452f.jpeg")
cv2 .namedWindow("input image", cv2.WINDOW_AUTOSIZE)
cv2.imshow("input image", src)
img = custom_blur_demo(src)
cv2.imwrite('output3.jpg', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
"""


#图像旋转
crop_image = lambda img, x0, y0, w, h: img[y0:y0+h, x0:x0+w]
def rotate_image(img, angle, crop):
    h, w = img.shape[:2]

    # 旋转角度的周期是360°
    angle %= 360

    # 用OpenCV内置函数计算仿射矩阵
    M_rotate = cv2.getRotationMatrix2D((w / 2, h / 2), angle, 1)

    # 得到旋转后的图像
    img_rotated = cv2.warpAffine(img, M_rotate, (w, h))

    # 如果需要裁剪去除黑边
    if crop:
        angle_crop = angle % 180  # 对于裁剪角度的等效周期是180°
        if angle_crop > 90:  # 并且关于90°对称
            angle_crop = 180 - angle_crop

        theta = angle_crop * np.pi / 180.0  # 转化角度为弧度
        hw_ratio = float(h) / float(w)  # 计算高宽比

        tan_theta = np.tan(theta)  # 计算裁剪边长系数的分子项
        numerator = np.cos(theta) + np.sin(theta) * tan_theta

        r = hw_ratio if h > w else 1 / hw_ratio  # 计算分母项中和宽高比相关的项
        denominator = r * tan_theta + 1  # 计算分母项

        crop_mult = numerator / denominator  # 计算最终的边长系数
        w_crop = int(round(crop_mult * w))  # 得到裁剪区域
        h_crop = int(round(crop_mult * h))
        x0 = int((w - w_crop) / 2)
        y0 = int((h - h_crop) / 2)
        img_rotated = crop_image(img_rotated, x0, y0, w_crop, h_crop)
    return img_rotated


#水平镜像
def mirror(image):
    h_flip = cv2.flip(image, 1)
    return h_flip
src = cv2.imread("99a1699d6b8fda3f5c4ccdef3139452f.jpeg")
#cv2 .namedWindow("input image", cv2.WINDOW_AUTOSIZE)
#cv2.imshow("input image", src)
img = mirror(src)
cv2.imwrite('shuiping.jpg', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
